Autor: Erick Bernardo
Customer Churn ou Rotatividade de Clientes refere-se a decisão tomada por clientes em abandonar os serviços prestados por uma empresa, finalizando assim o relacionamento comercial entre ambos. O percentual de rotatividade de clientes complementa o percentual de fidelidade de clientes somando ambos 100%.
Empresas buscam fidelizar seus clientes, principalmente aqueles que trazem os maiores lucros para a empresa. Assim é uma vantagem comercial conseguir prever quais os clientes que possuem a maior probabilidade de encerrarem seus relacionamentos comerciais com a empresa, bem como as características de tais clientes para que políticas internas possam ser planejadas.
Neste projeto implementa-se um modelo preditivo para prever o Customer Churn de uma operadora de telecomunicações, utilizando-se a linguagem Python e um dataset disponível no Kaggle.
# Instalação de biblioteca para tratar variáveis categóricas
# !pip install category_encoders
# !pip install mlxtend
# Importando bibliotecas de manipulação de dados
import numpy as np
import pandas as pd
# Importando bibliotecas para visualização de dados
import matplotlib.pyplot as plt
import seaborn as sns
# Importando bibliotecas, para a plotagem de gráficos interativos com o plotly.
import plotly.offline as py
import plotly.graph_objs as go
import plotly.figure_factory as ff
py.init_notebook_mode(connected = False)
# Importando classes para cálculo de estatísticas.
from scipy.stats import kurtosis, skew
# Importando bibliotecas de técnicas de pré-processamento e redução de dimensionalidade
from sklearn.preprocessing import MinMaxScaler, StandardScaler, PowerTransformer, normalize, LabelEncoder, OneHotEncoder
from sklearn.impute import SimpleImputer
from sklearn.decomposition import PCA
# Importando biblioteca com várias técnicas de tratamento de variáveis categóricas
import category_encoders as ce
# Importando biliotecas, para a fase de Feature Selection.
from sklearn.decomposition import PCA
from mlxtend.feature_selection import SequentialFeatureSelector as SFS
from sklearn.feature_selection import SelectKBest, SelectPercentile, mutual_info_classif, f_classif, RFE, chi2
# Importando bibliotecas, para tarefas de Data Munging.
from sklearn.feature_selection import VarianceThreshold
# Importando bibliotecas de técnicas de selação de modelos (holdout e busca aleatória)
from sklearn.model_selection import train_test_split, RandomizedSearchCV
from sklearn.model_selection import GridSearchCV
# Importando bibliotecas, para a etapa de modelagem preditiva.
import xgboost as xgb
from sklearn import tree
from sklearn.svm import SVC
from sklearn.naive_bayes import GaussianNB
from sklearn.tree import DecisionTreeClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import KFold, cross_val_score
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.ensemble import RandomForestClassifier, ExtraTreesClassifier, AdaBoostClassifier, GradientBoostingClassifier
from sklearn.neural_network import MLPClassifier
# Importando biblioteca de estruturação de etapas de análise preditiva
from sklearn.pipeline import Pipeline
# Importando biblioteca de métricas de desempenho de técnicas de machine learning
from sklearn.metrics import confusion_matrix, classification_report
from sklearn.metrics import accuracy_score, balanced_accuracy_score, average_precision_score, precision_score
from sklearn.metrics import recall_score, f1_score, roc_auc_score, cohen_kappa_score
# Importando biblioteca para carregar e salvar modelos preditivos em arquivos externos
import pickle
# Importando biblioteca para ocultar Future Warnings.
import warnings
warnings.simplefilter(action = 'ignore', category = FutureWarning)
# Importando biblioteca para carregar arquivos no google colab
#from google.colab import files
O dataset foi escolhido por fornecer dados de uma grande empresa de telecomunicações envolvendo variáveis categóricas e quantitativas.
Kaggle: Telecom Churn Dataset
The Orange Telecom's Churn Dataset, which consists of cleaned customer activity data (features), along with a churn label specifying whether a customer canceled the subscription, will be used to develop predictive models. Two datasets are made available here: The churn-80 and churn-20 datasets can be downloaded.
The two sets are from the same batch, but have been split by an 80/20 ratio. As more data is often desirable for developing ML models, let's use the larger set (that is, churn-80) for training and cross-validation purposes, and the smaller set (that is, churn-20) for final testing and model performance evaluation.
O dataset escolhido já encontra-se separado em dados de treino e teste.
# Carregando o conjunto de dados de treino
dataTrain = pd.read_csv('data\churn-bigml-80.csv')
# Visualizando primeiras linhas
dataTrain.head()
| State | Account length | Area code | International plan | Voice mail plan | Number vmail messages | Total day minutes | Total day calls | Total day charge | Total eve minutes | Total eve calls | Total eve charge | Total night minutes | Total night calls | Total night charge | Total intl minutes | Total intl calls | Total intl charge | Customer service calls | Churn | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | KS | 128 | 415 | No | Yes | 25 | 265.1 | 110 | 45.07 | 197.4 | 99 | 16.78 | 244.7 | 91 | 11.01 | 10.0 | 3 | 2.70 | 1 | False |
| 1 | OH | 107 | 415 | No | Yes | 26 | 161.6 | 123 | 27.47 | 195.5 | 103 | 16.62 | 254.4 | 103 | 11.45 | 13.7 | 3 | 3.70 | 1 | False |
| 2 | NJ | 137 | 415 | No | No | 0 | 243.4 | 114 | 41.38 | 121.2 | 110 | 10.30 | 162.6 | 104 | 7.32 | 12.2 | 5 | 3.29 | 0 | False |
| 3 | OH | 84 | 408 | Yes | No | 0 | 299.4 | 71 | 50.90 | 61.9 | 88 | 5.26 | 196.9 | 89 | 8.86 | 6.6 | 7 | 1.78 | 2 | False |
| 4 | OK | 75 | 415 | Yes | No | 0 | 166.7 | 113 | 28.34 | 148.3 | 122 | 12.61 | 186.9 | 121 | 8.41 | 10.1 | 3 | 2.73 | 3 | False |
# Shape do dataframe
dataTrain.shape
(2666, 20)
# Carregando o conjunto de dados de teste
dataTest = pd.read_csv('data\churn-bigml-20.csv')
#Visualizando primeiras linhas
dataTest.head()
| State | Account length | Area code | International plan | Voice mail plan | Number vmail messages | Total day minutes | Total day calls | Total day charge | Total eve minutes | Total eve calls | Total eve charge | Total night minutes | Total night calls | Total night charge | Total intl minutes | Total intl calls | Total intl charge | Customer service calls | Churn | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | LA | 117 | 408 | No | No | 0 | 184.5 | 97 | 31.37 | 351.6 | 80 | 29.89 | 215.8 | 90 | 9.71 | 8.7 | 4 | 2.35 | 1 | False |
| 1 | IN | 65 | 415 | No | No | 0 | 129.1 | 137 | 21.95 | 228.5 | 83 | 19.42 | 208.8 | 111 | 9.40 | 12.7 | 6 | 3.43 | 4 | True |
| 2 | NY | 161 | 415 | No | No | 0 | 332.9 | 67 | 56.59 | 317.8 | 97 | 27.01 | 160.6 | 128 | 7.23 | 5.4 | 9 | 1.46 | 4 | True |
| 3 | SC | 111 | 415 | No | No | 0 | 110.4 | 103 | 18.77 | 137.3 | 102 | 11.67 | 189.6 | 105 | 8.53 | 7.7 | 6 | 2.08 | 2 | False |
| 4 | HI | 49 | 510 | No | No | 0 | 119.3 | 117 | 20.28 | 215.1 | 109 | 18.28 | 178.7 | 90 | 8.04 | 11.1 | 1 | 3.00 | 1 | False |
# Shape do dataframe
dataTest.shape
(667, 20)
O conjunto de treino e teste foi fornecido separado, para as etapas de pré-processamento ambos conjuntos são concatenados para que sejam tratados como um único conjunto de dados.
# Identificação dos dados de treino na variável Train ( Train = 1, treino)
dataTrain['Train'] = 1
dataTest['Train'] = 0
# Unindo dados de treino e de teste em um único conjunto de dados.
dataOrig = pd.concat([dataTrain, dataTest])
# Visualizando shape do dataframe
dataOrig.shape
(3333, 21)
# Verificando a dimensão do dataset.
dataOrig.shape
(3333, 21)
3333 observações e 21 colunas.
# Verificando o número de valores únicos em cada coluna e seus respectivos tipo de dados
# Atribuindo a contagem de valores únicos
dataType = dataOrig.nunique()
# Convertendo a um data frame e nomeando a coluna "Nunique"
dataType = pd.DataFrame(data = dataType.values, index = dataType.index, columns = ['Nunique'] )
# Atribuindo o tipo de dado de cada coluna na coluna "dtype"
dataType['dtype'] = dataOrig.dtypes
# Ordenando por Nunique
dataTypeTrain = dataType.sort_values(by=['Nunique'])
dataTypeTrain
| Nunique | dtype | |
|---|---|---|
| Train | 2 | int64 |
| International plan | 2 | object |
| Voice mail plan | 2 | object |
| Churn | 2 | bool |
| Area code | 3 | int64 |
| Customer service calls | 10 | int64 |
| Total intl calls | 21 | int64 |
| Number vmail messages | 46 | int64 |
| State | 51 | object |
| Total day calls | 119 | int64 |
| Total night calls | 120 | int64 |
| Total eve calls | 123 | int64 |
| Total intl minutes | 162 | float64 |
| Total intl charge | 162 | float64 |
| Account length | 212 | int64 |
| Total night charge | 933 | float64 |
| Total eve charge | 1440 | float64 |
| Total night minutes | 1591 | float64 |
| Total eve minutes | 1611 | float64 |
| Total day minutes | 1667 | float64 |
| Total day charge | 1667 | float64 |
Observa-se a presença de 5 variáveis categóricas no dataset incluindo a variável target Churn. As demais são as features: International plan, Voice mail plan, Area code e State.
Area code embora esteja identificada como numérica será convertida para o tipo "category", junto com as outras identificadas como "object".
# Verificando o número de registros duplicados.
dataOrig.duplicated().sum()
0
# Verificando o número de valores ausentes existentes dentro do dataset.
dataOrig.isna().sum()
State 0 Account length 0 Area code 0 International plan 0 Voice mail plan 0 Number vmail messages 0 Total day minutes 0 Total day calls 0 Total day charge 0 Total eve minutes 0 Total eve calls 0 Total eve charge 0 Total night minutes 0 Total night calls 0 Total night charge 0 Total intl minutes 0 Total intl calls 0 Total intl charge 0 Customer service calls 0 Churn 0 Train 0 dtype: int64
Inicialmente são realizados as seguintes transformações:
# Visualização dos nomes das colunas.
dataOrig.columns
Index(['State', 'Account length', 'Area code', 'International plan',
'Voice mail plan', 'Number vmail messages', 'Total day minutes',
'Total day calls', 'Total day charge', 'Total eve minutes',
'Total eve calls', 'Total eve charge', 'Total night minutes',
'Total night calls', 'Total night charge', 'Total intl minutes',
'Total intl calls', 'Total intl charge', 'Customer service calls',
'Churn', 'Train'],
dtype='object')
# Remoção dos espaços em branco nos nomes das colunas.
dataOrig.columns = [x.replace(' ','_') for x in dataOrig.columns]
dataOrig.columns
Index(['State', 'Account_length', 'Area_code', 'International_plan',
'Voice_mail_plan', 'Number_vmail_messages', 'Total_day_minutes',
'Total_day_calls', 'Total_day_charge', 'Total_eve_minutes',
'Total_eve_calls', 'Total_eve_charge', 'Total_night_minutes',
'Total_night_calls', 'Total_night_charge', 'Total_intl_minutes',
'Total_intl_calls', 'Total_intl_charge', 'Customer_service_calls',
'Churn', 'Train'],
dtype='object')
# Conversão das features State, Area_code, International_plan, Voice_mail_plan e churn para o data type category
dataOrig['State'] = dataOrig['State'].astype('category')
dataOrig['Area_code'] = dataOrig['Area_code'].astype('category')
dataOrig['International_plan'] = dataOrig['International_plan'].astype('category')
dataOrig['Voice_mail_plan'] = dataOrig['Voice_mail_plan'].astype('category')
dataOrig['Churn'] = dataOrig['Churn'].astype('category')
# Mapeamento da variável target Churn para valores nominais
target_map = {True: 'Yes', False: 'No'}
# Mapeando as classes com seus valores nominais
dataOrig['Churn'] = dataOrig['Churn'].map(target_map)
dataOrig.head()
| State | Account_length | Area_code | International_plan | Voice_mail_plan | Number_vmail_messages | Total_day_minutes | Total_day_calls | Total_day_charge | Total_eve_minutes | ... | Total_eve_charge | Total_night_minutes | Total_night_calls | Total_night_charge | Total_intl_minutes | Total_intl_calls | Total_intl_charge | Customer_service_calls | Churn | Train | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | KS | 128 | 415 | No | Yes | 25 | 265.1 | 110 | 45.07 | 197.4 | ... | 16.78 | 244.7 | 91 | 11.01 | 10.0 | 3 | 2.70 | 1 | No | 1 |
| 1 | OH | 107 | 415 | No | Yes | 26 | 161.6 | 123 | 27.47 | 195.5 | ... | 16.62 | 254.4 | 103 | 11.45 | 13.7 | 3 | 3.70 | 1 | No | 1 |
| 2 | NJ | 137 | 415 | No | No | 0 | 243.4 | 114 | 41.38 | 121.2 | ... | 10.30 | 162.6 | 104 | 7.32 | 12.2 | 5 | 3.29 | 0 | No | 1 |
| 3 | OH | 84 | 408 | Yes | No | 0 | 299.4 | 71 | 50.90 | 61.9 | ... | 5.26 | 196.9 | 89 | 8.86 | 6.6 | 7 | 1.78 | 2 | No | 1 |
| 4 | OK | 75 | 415 | Yes | No | 0 | 166.7 | 113 | 28.34 | 148.3 | ... | 12.61 | 186.9 | 121 | 8.41 | 10.1 | 3 | 2.73 | 3 | No | 1 |
5 rows × 21 columns
# Visualização das alterações
dataOrig.info()
<class 'pandas.core.frame.DataFrame'> Int64Index: 3333 entries, 0 to 666 Data columns (total 21 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 State 3333 non-null category 1 Account_length 3333 non-null int64 2 Area_code 3333 non-null category 3 International_plan 3333 non-null category 4 Voice_mail_plan 3333 non-null category 5 Number_vmail_messages 3333 non-null int64 6 Total_day_minutes 3333 non-null float64 7 Total_day_calls 3333 non-null int64 8 Total_day_charge 3333 non-null float64 9 Total_eve_minutes 3333 non-null float64 10 Total_eve_calls 3333 non-null int64 11 Total_eve_charge 3333 non-null float64 12 Total_night_minutes 3333 non-null float64 13 Total_night_calls 3333 non-null int64 14 Total_night_charge 3333 non-null float64 15 Total_intl_minutes 3333 non-null float64 16 Total_intl_calls 3333 non-null int64 17 Total_intl_charge 3333 non-null float64 18 Customer_service_calls 3333 non-null int64 19 Churn 3333 non-null category 20 Train 3333 non-null int64 dtypes: category(5), float64(8), int64(8) memory usage: 462.2 KB
# Definição de uma função para plotar gráficos interativos em um ambiente jupyter não-padrão.
def configure_plotly_browser_state():
import IPython
display(IPython.core.display.HTML('''
<script src="/static/components/requirejs/require.js"></script>
<script>
requirejs.config({
paths: {
base: '/static/base',
plotly: 'https://cdn.plot.ly/plotly-1.43.1.min.js?noext',
},
});
</script>
'''))
# Definindo uma função para criar gráficos de Barra interativos com o plotly.
def plotBar(data, col = '', target = '', title = '', yaxis = '', xaxis = '', kind = 'normal',
color = ['#8783D1', '#FADF63', '#FF9F43', '#EE6352', '#FC7A1E'], opacity = 0.65,
template = 'plotly_white', orientation = 'v', barmode = 'group'):
# Realizando as pré-configurações necessárias para a plotagem do gráfico interativo.
configure_plotly_browser_state()
# Criando gráficos na vertical.
if orientation == 'v':
# Plotando gráfico de barras simples, sem agrupamento.
if kind == 'normal':
# Definindo os dados, a cor, orientação e a transparência que serão utilizados para criar as barras.
dataTrace = go.Bar(
x = data.index,
y = data.values,
marker = {'color': color[2], "opacity": opacity},
orientation = orientation
)
# Plotando gráfico de barras agrupado por uma variável categórica.
elif kind == 'groups':
# Captura os registros pertencentes a cada categoria da variável categórica.
g = [data[data[target] == cat] for cat in data[target].cat.categories]
# Definindo os dados, a cor, orientação e a transparência que serão utilizados para criar as barras.
dataTrace = [
go.Bar(
x = g[cat][col],
y = g[cat]['count'],
name = data[target].cat.categories[cat].capitalize(),
marker = {'color': color[cat], "opacity": opacity},
orientation = orientation
) for cat in range(0,len(g))
]
# Criando gráficos na horizontal.
else:
# Plotando gráfico de barras simples.
if kind == 'normal':
# Definindo os dados, a cor, orientação e a transparência que serão utilizados para criar as barras.
dataTrace = go.Bar(
x = data.values,
y = data.index,
marker = {'color': color[3], "opacity": opacity},
orientation = orientation
)
# Plotando gráfico de barras agrupado por uma variável categórica.
elif kind == 'groups':
# Captura os registros pertencentes a cada categoria, da variável categórica.
g = [data[data[target] == cat] for cat in data[target].cat.categories]
# Definindo os dados, a cor, orientação e a transparência que serão utilizados para criar as barras.
dataTrace = [
go.Bar(
x = g[cat]['count'],
y = g[cat][col],
name = data[target].cat.categories[cat].capitalize(),
marker = {'color': color[cat], "opacity": opacity},
orientation = orientation
) for cat in range(0,len(g))
]
# Defindo as configurações de layout.
layout = go.Layout(
title = title,
yaxis = {'title': yaxis},
xaxis = {'title': xaxis},
template = template
)
# Criando uma Figure com os dados e o layout defindos.
fig = go.Figure(data = dataTrace, layout = layout)
# Definindo que as barras devem ser dispostas uma ao lado da outra caso estejam agrupadas por categoria.
# Para criar Stacked Bars, utilize: 'stack'.
fig.update_layout(barmode = barmode)
# Plotando o Figure com o pyplot.
fig.show()
# Definindo uma função para criar Histogramas interativos com o plotly.
def plotHist(data, col = '', target = '', title = '', yaxis = '', xaxis = '',
groups = False, color = ['#8783D1', '#FADF63', '#EF476F'],
opacity = 0.65, template = 'plotly_white'):
# Realizando as pré-configurações necessárias, para a plotagem do gráfico interativo.
configure_plotly_browser_state()
# Criando um histograma para um conjunto de dados.
if groups == False:
# Definindo os dados, a cor, e a transparência que serão utilizados para criar o Histograma.
dataTrace = go.Histogram(x = data, marker = {'color': color[2], "opacity": opacity})
# Criando um histograma para um conjunto de dados agrupado por categorias.
else:
# Captura os registros pertencentes a cada categoria, da variável categórica.
g = [data[data[target] == cat] for cat in data[target].cat.categories]
# Definindo os dados, a cor, e a transparência que serão utilizados para criar cada um dos Histogramas.
dataTrace = [
go.Histogram(
x = g[cat][col],
name = data[target].cat.categories[cat].capitalize(),
marker = {'color': color[cat], "opacity": opacity}
) for cat in range(0,len(g))
]
# Defindo as configurações de layout.
layout = go.Layout(
title = title,
yaxis = {'title': yaxis},
xaxis = {'title': xaxis},
bargap = 0.05,
template = template
)
# Criando uma Figure com os dados e o layout defindos.
fig = go.Figure(data = dataTrace, layout = layout)
# Plotando o Figure com o pyplot.
py.iplot(fig)
# Definindo uma função para realizar a plotagem de gráficos de pizza.
def plotPie(data, title = ''):
# Realizando as pré-configurações necessárias, para a plotagem do gráfico interativo.
configure_plotly_browser_state()
# Defindo as configurações de layout.
layout = go.Layout (
title = title
)
# Criando uma Figure, com os dados e o layout defindos.
fig = go.Figure (
data = [go.Pie(labels = [i[0].upper() + i[1:] for i in dataCounts.index], values = dataCounts.values, hole = .1)],
layout = layout
)
# Adicionando uma borda branca em cada uma das fatias da pizza.
fig.update_traces (
marker = dict (
line = dict (
color = '#FFFFFF',
width = 1
)
)
)
# Plotando a Figure com o pyplot.
fig.show()
# Definindo uma função para criar gráficos de Boxplot interativos com o plotly.
def plotBoxplot(data, name = '', col = '', target = '', title = '', yaxis = '',
xaxis = '', kind = 'normal',
color = ['#8783D1', '#FADF63', '#06D6A0', '#662E9B'],
opacity = 0.65,
template = 'plotly_white',
orientation = 'v'):
# Realizando as pré-configurações necessárias, para a plotagem do gráfico interativo.
configure_plotly_browser_state()
# Plota gráficos de um ou mais boxplots simples.
if kind == 'normal':
# Plota gráficos verticais.
if orientation == 'v':
# Definindo os dados, a cor, o nome e a transparência que serão utilizados para criar cada um dos boxplots.
dataTrace = [
go.Box(
y = data[l],
name = l if name == '' else name,
marker = {'color': color[2], "opacity": opacity}
) for l in data.columns
]
# Plota gráficos horizontais.
else:
# Definindo os dados, a cor, o nome e a transparência que serão utilizados para criar cada um dos boxplots.
dataTrace = [
go.Box(
x = data[l],
name = l if name == '' else name,
marker = {'color': color[3], "opacity": opacity}
) for l in data.columns
]
# Plota gráficos boxplot, para uma variável numérica, agrupada por uma variável categórica.
elif kind == 'groups':
# Captura os registros pertencentes a cada categoria, da variável categórica.
g = [data[data[target] == cat] for cat in data[target].cat.categories]
# Converte a primeira letra do nome de cada categoria para maiúscula.
name = [n.capitalize() for n in data[target].cat.categories]
# Plota gráficos verticais.
if orientation == 'v':
# Definindo os dados, a cor, o nome e a transparência que serão utilizados para criar cada um dos boxplots.
dataTrace = [
go.Box(
y = g[l][col],
name = name[l],
marker = {'color': color[l], "opacity": opacity}
) for l in range(0, len(g))
]
# Plota gráficos horizontais.
else:
# Definindo os dados, a cor, o nome e a transparência que serão utilizados para criar cada um dos boxplots.
dataTrace = [
go.Box(
x = g[l][col],
name = name[l],
marker = {'color': color[l], "opacity": opacity}
) for l in range(0, len(g))
]
# Defindo as configurações de layout.
layout = go.Layout (
title = title,
yaxis = {'title': yaxis},
xaxis = {'title': xaxis},
template = template
)
# Criando uma Figure com os dados e o layout defindos.
fig = go.Figure(data = dataTrace, layout = layout)
# Plotando o Figure com o pyplot.
py.iplot(fig)
# Definindo uma função para gerar estatísticas de uma variável do dataset.
def varStats(col, data, target = ''):
if target == '':
# Criando um dataframe, com as estatísticas da variável especificada.
stats = pd.DataFrame({
'min' : data[col].min(),
'Q1' : data[col].quantile(.25),
'Median': data[col].median(),
'Mean' : data[col].mean(),
'Q3' : data[col].quantile(.75),
'SD' : data[col].std(),
'Sk' : skew(data[col]),
'Ck' : kurtosis(data[col])
}, index = [col])
else:
# Criando um dataframe com as estatísticas da variável especificada, agrupada pela variável target.
stats = pd.concat([
dataOrig[[col, target]].groupby(target).min(),
dataOrig[[col, target]].groupby(target).quantile(.25),
dataOrig[[col, target]].groupby(target).median(),
dataOrig[[col, target]].groupby(target).mean(),
dataOrig[[col, target]].groupby(target).quantile(.75),
dataOrig[[col, target]].groupby(target).std(),
dataOrig[[col, target]].groupby(target).skew(),
dataOrig[[col, target]].groupby(target).apply(lambda group: kurtosis(group)[0])
], axis = 1)
# Renomeando as colunas do DataFrame.
stats.columns = ['min', 'Q1', 'Median', 'Mean', 'Q3', 'SD', 'Sk', 'Ck']
# Retornando os resultados obtidos.
return stats
# Definindo o nome da variável a ser analisada.
col = 'State'
# Definindo o nome da variável Target.
target = 'Churn'
# Definindo a descrição da variável nos gráficos.
label = 'Estados'
# Capturando variáveis especificadas do Dataset.
data = dataOrig[[col, target]]
# Criando uma variável count para contabilizar as ocorrências de cada registro.
data['count'] = 1
# Agrupando dados e contabilizando o número de ocorrências.
data = data.groupby(by = [target, col]).sum()
# Reorganizando DataFrame.
data = data.reset_index()
# Plotando um gráfico de barras para a variável especificada.
plotBar (
data = data,
col = col,
target = target,
title = 'Churn dos clientes por ' + label,
yaxis = 'Frequência Absoluta',
xaxis = label,
kind = 'groups'
)
# Frequência absoluta para a variável analisada
# Contabilizando a frequência absoluta, de cada categoria presente na variável especificada.
dataCounts = dataOrig[col].value_counts()
# Plotando um gráfico de barras para a variável especificada.
plotBar (
data = dataCounts,
title = 'Frequência absoluta das categorias da Feature ' + col,
yaxis = 'Frequência Absoluta',
xaxis = label
)
# Plotando um gráfico de pizza para a variável especificada.
plotPie (
data = dataCounts,
title = 'Frequência relativa das categorias da feature ' + col
)
# Definindo o nome da variável a ser analisada.
col = 'Area_code'
# Definindo o nome da variável Target.
target = 'Churn'
# Definindo a descrição da variável nos gráficos.
label = 'Código de Área'
# Capturando variáveis especificadas do Dataset.
data = dataOrig[[col, target]]
# Criando uma variável count para contabilizar as ocorrências de cada registro.
data['count'] = 1
# Agrupando dados e contabilizando o número de ocorrências.
data = data.groupby(by = [target, col]).sum()
# Reorganizando DataFrame.
data = data.reset_index()
# Transformando variável alvo em String.
data[col] = data[col].apply(lambda c: str(c) + ' Code')
# Plotando um gráfico de barras para a variável especificada.
plotBar (
data = data,
col = col,
target = target,
title = 'Churn dos clientes por ' + label,
yaxis = 'Frequência Absoluta',
xaxis = label,
kind = 'groups'
)
# Contabilizando a frequência absoluta, de cada categoria presente na variável especificada.
dataCounts = dataOrig[col].value_counts()
# Alterando índices do DataFrame.
dataCounts.index = [str(i) + ' Code' for i in dataCounts.index]
# Plotando um gráfico de barras para a variável especificada.
plotBar (
data = dataCounts,
title = 'Frequência absoluta das categorias da Feature ' + col,
yaxis = 'Frequência Absoluta',
xaxis = label
)
# Plotando um gráfico de pizza para a variável especificada.
plotPie (
data = dataCounts,
title = 'Frequência relativa das categorias da feature ' + col
)
# Definindo o nome da variável a ser analisada.
col = 'International_plan'
# Definindo o nome da variável Target.
target = 'Churn'
# Definindo a descrição da variável nos gráficos.
label = 'Plano Internacional'
# Capturando variáveis especificadas do Dataset.
data = dataOrig[[col, target]]
# Criando uma variável count para contabilizar as ocorrências de cada registro.
data['count'] = 1
# Agrupando dados e contabilizando o número de ocorrências.
data = data.groupby(by = [target, col]).sum()
# Reorganizando DataFrame.
data = data.reset_index()
# Capitalizando valores da variável alvo.
data[col] = data[col].apply(lambda c: c.capitalize())
# Plotando um gráfico de barras para a variável especificada.
plotBar (
data = data,
col = col,
target = target,
title = 'Churn dos clientes por ' + label,
yaxis = 'Frequência Absoluta',
xaxis = label,
kind = 'groups'
)
# Contabilizando a frequência absoluta, de cada categoria presente na variável especificada.
dataCounts = dataOrig[col].value_counts()
# Plotando um gráfico de barras para a variável especificada.
plotBar (
data = dataCounts,
title = 'Frequência absoluta das categorias da Feature ' + col,
yaxis = 'Frequência Absoluta',
xaxis = label
)
# Plotando um gráfico de pizza para a variável especificada.
plotPie (
data = dataCounts,
title = 'Frequência relativa das categorias da feature ' + col
)
# Definindo o nome da variável a ser analisada.
col = 'Voice_mail_plan'
# Definindo o nome da variável Target.
target = 'Churn'
# Definindo a descrição da variável nos gráficos.
label = 'Plano de Correio de Voz'
# Capturando variáveis especificadas do Dataset.
data = dataOrig[[col, target]]
# Criando uma variável count para contabilizar as ocorrências de cada registro.
data['count'] = 1
# Agrupando dados e contabilizando o número de ocorrências.
data = data.groupby(by = [target, col]).sum()
# Reorganizando DataFrame.
data = data.reset_index()
# Capitalizando valores da variável alvo.
data[col] = data[col].apply(lambda c: c.capitalize())
# Plotando um gráfico de barras para a variável especificada.
plotBar (
data = data,
col = col,
target = target,
title = 'Churn dos clientes por ' + label,
yaxis = 'Frequência Absoluta',
xaxis = label,
kind = 'groups'
)
# Contabilizando a frequência absoluta, de cada categoria presente na variável especificada.
dataCounts = dataOrig[col].value_counts()
# Plotando um gráfico de barras para a variável especificada.
plotBar (
data = dataCounts,
title = 'Frequência absoluta das categorias da Feature ' + col,
yaxis = 'Frequência Absoluta',
xaxis = label
)
# Plotando um gráfico de pizza para a variável especificada.
plotPie (
data = dataCounts,
title = 'Frequência relativa das categorias da feature ' + col
)
# Definindo o nome da variável a ser analisada.
col = 'Account_length'
# Definindo o nome da variável Target.
target = 'Churn'
# Definindo a descrição da variável nos gráficos.
label = 'Tamanho da Conta'
# Capturando variáveis especificadas do Dataset.
data = dataOrig[[col, target]]
# Criando uma variável count para contabilizar as ocorrências de cada registro.
data['count'] = 1
# Agrupando dados e contabilizando o número de ocorrências.
data = data.groupby(by = [target, col]).sum()
# Reorganizando DataFrame.
data = data.reset_index()
# Plotando um gráfico de histograma para a variável especificada.
plotHist (
data = dataOrig[[col, target]],
title = 'Histograma para a variável ' + col,
xaxis = label,
yaxis = 'Frequência Absoluta',
col = col,
target = target,
groups = True
)
# Plotando um gráfico de boxplot para a variável especificada.
plotBoxplot (
data = dataOrig[[col, target]],
title = 'Boxplot para a variável ' + col,
yaxis = label,
xaxis = target.capitalize(),
col = col,
target = target,
kind = 'groups'
)
# Calculando algumas estatísticas para a variável especificada.
varStats(col = col, data = dataOrig, target = target)
| min | Q1 | Median | Mean | Q3 | SD | Sk | Ck | |
|---|---|---|---|---|---|---|---|---|
| Churn | ||||||||
| No | 1 | 73.0 | 100 | 100.793684 | 127.0 | 39.88235 | 0.090523 | -0.135657 |
| Yes | 1 | 76.0 | 103 | 102.664596 | 127.0 | 39.46782 | 0.137132 | 0.043640 |
# Definindo o nome da variável a ser analisada.
col = 'Number_vmail_messages'
# Definindo o nome da variável Target.
target = 'Churn'
# Definindo a descrição da variável nos gráficos.
label = 'Number_vmail_messages'
# Capturando variáveis especificadas do Dataset.
data = dataOrig[[col, target]]
# Criando uma variável count para contabilizar as ocorrências de cada registro.
data['count'] = 1
# Agrupando dados e contabilizando o número de ocorrências.
data = data.groupby(by = [target, col]).sum()
# Reorganizando DataFrame.
data = data.reset_index()
# Plotando um gráfico de histograma para a variável especificada.
plotHist (
data = dataOrig[[col, target]],
title = 'Histograma para a variável ' + col,
xaxis = label,
yaxis = 'Frequência Absoluta',
col = col,
target = target,
groups = True
)
# Plotando um gráfico de boxplot para a variável especificada.
plotBoxplot (
data = dataOrig[[col, target]],
title = 'Boxplot para a variável ' + col,
yaxis = label,
xaxis = target.capitalize(),
col = col,
target = target,
kind = 'groups'
)
# Calculando algumas estatísticas para a variável especificada.
varStats(col = col, data = dataOrig, target = target)
| min | Q1 | Median | Mean | Q3 | SD | Sk | Ck | |
|---|---|---|---|---|---|---|---|---|
| Churn | ||||||||
| No | 0 | 0.0 | 0 | 8.604561 | 22.0 | 13.913125 | 1.167435 | -0.292254 |
| Yes | 0 | 0.0 | 0 | 5.115942 | 0.0 | 11.860138 | 2.040412 | 2.524606 |
# Definindo o nome da variável a ser analisada.
col = 'Total_day_minutes'
# Definindo o nome da variável Target.
target = 'Churn'
# Definindo a descrição da variável nos gráficos.
label = 'Total_day_minutes'
# Capturando variáveis especificadas do Dataset.
data = dataOrig[[col, target]]
# Criando uma variável count para contabilizar as ocorrências de cada registro.
data['count'] = 1
# Agrupando dados e contabilizando o número de ocorrências.
data = data.groupby(by = [target, col]).sum()
# Reorganizando DataFrame.
data = data.reset_index()
# Plotando um gráfico de histograma para a variável especificada.
plotHist (
data = dataOrig[[col, target]],
title = 'Histograma para a variável ' + col,
xaxis = label,
yaxis = 'Frequência Absoluta',
col = col,
target = target,
groups = True
)
# Plotando um gráfico de boxplot para a variável especificada.
plotBoxplot (
data = dataOrig[[col, target]],
title = 'Boxplot para a variável ' + col,
yaxis = label,
xaxis = target.capitalize(),
col = col,
target = target,
kind = 'groups'
)
# Calculando algumas estatísticas para a variável especificada.
varStats(col = col, data = dataOrig, target = target)
| min | Q1 | Median | Mean | Q3 | SD | Sk | Ck | |
|---|---|---|---|---|---|---|---|---|
| Churn | ||||||||
| No | 0.0 | 142.825 | 177.2 | 175.175754 | 210.30 | 50.181655 | -0.226378 | -0.006024 |
| Yes | 0.0 | 153.250 | 217.6 | 206.914079 | 265.95 | 68.997792 | -0.199223 | -0.813099 |
# Definindo o nome da variável a ser analisada.
col = 'Total_day_calls'
# Definindo o nome da variável Target.
target = 'Churn'
# Definindo a descrição da variável nos gráficos.
label = 'Total_day_calls'
# Capturando variáveis especificadas do Dataset.
data = dataOrig[[col, target]]
# Criando uma variável count para contabilizar as ocorrências de cada registro.
data['count'] = 1
# Agrupando dados e contabilizando o número de ocorrências.
data = data.groupby(by = [target, col]).sum()
# Reorganizando DataFrame.
data = data.reset_index()
# Plotando um gráfico de histograma para a variável especificada.
plotHist (
data = dataOrig[[col, target]],
title = 'Histograma para a variável ' + col,
xaxis = label,
yaxis = 'Frequência Absoluta',
col = col,
target = target,
groups = True
)
# Plotando um gráfico de boxplot para a variável especificada.
plotBoxplot (
data = dataOrig[[col, target]],
title = 'Boxplot para a variável ' + col,
yaxis = label,
xaxis = target.capitalize(),
col = col,
target = target,
kind = 'groups'
)
# Calculando algumas estatísticas para a variável especificada.
varStats(col = col, data = dataOrig, target = target)
| min | Q1 | Median | Mean | Q3 | SD | Sk | Ck | |
|---|---|---|---|---|---|---|---|---|
| Churn | ||||||||
| No | 0 | 87.0 | 100 | 100.283158 | 114.0 | 19.801157 | -0.063296 | 0.124995 |
| Yes | 0 | 87.5 | 103 | 101.335404 | 116.5 | 21.582307 | -0.353392 | 0.709753 |
# Definindo o nome da variável a ser analisada.
col = 'Total_day_charge'
# Definindo o nome da variável Target.
target = 'Churn'
# Definindo a descrição da variável nos gráficos.
label = 'Total_day_charge'
# Capturando variáveis especificadas do Dataset.
data = dataOrig[[col, target]]
# Criando uma variável count para contabilizar as ocorrências de cada registro.
data['count'] = 1
# Agrupando dados e contabilizando o número de ocorrências.
data = data.groupby(by = [target, col]).sum()
# Reorganizando DataFrame.
data = data.reset_index()
# Plotando um gráfico de histograma para a variável especificada.
plotHist (
data = dataOrig[[col, target]],
title = 'Histograma para a variável ' + col,
xaxis = label,
yaxis = 'Frequência Absoluta',
col = col,
target = target,
groups = True
)
# Plotando um gráfico de boxplot para a variável especificada.
plotBoxplot (
data = dataOrig[[col, target]],
title = 'Boxplot para a variável ' + col,
yaxis = label,
xaxis = target.capitalize(),
col = col,
target = target,
kind = 'groups'
)
# Calculando algumas estatísticas para a variável especificada.
varStats(col = col, data = dataOrig, target = target)
| min | Q1 | Median | Mean | Q3 | SD | Sk | Ck | |
|---|---|---|---|---|---|---|---|---|
| Churn | ||||||||
| No | 0.0 | 24.2825 | 30.12 | 29.780421 | 35.75 | 8.530835 | -0.226405 | -0.005913 |
| Yes | 0.0 | 26.0550 | 36.99 | 35.175921 | 45.21 | 11.729710 | -0.199209 | -0.813006 |
# Definindo o nome da variável a ser analisada.
col = 'Total_eve_minutes'
# Definindo o nome da variável Target.
target = 'Churn'
# Definindo a descrição da variável nos gráficos.
label = 'Total_eve_minutes'
# Capturando variáveis especificadas do Dataset.
data = dataOrig[[col, target]]
# Criando uma variável count para contabilizar as ocorrências de cada registro.
data['count'] = 1
# Agrupando dados e contabilizando o número de ocorrências.
data = data.groupby(by = [target, col]).sum()
# Reorganizando DataFrame.
data = data.reset_index()
# Plotando um gráfico de histograma para a variável especificada.
plotHist (
data = dataOrig[[col, target]],
title = 'Histograma para a variável ' + col,
xaxis = label,
yaxis = 'Frequência Absoluta',
col = col,
target = target,
groups = True
)
# Plotando um gráfico de boxplot para a variável especificada.
plotBoxplot (
data = dataOrig[[col, target]],
title = 'Boxplot para a variável ' + col,
yaxis = label,
xaxis = target.capitalize(),
col = col,
target = target,
kind = 'groups'
)
# Calculando algumas estatísticas para a variável especificada.
varStats(col = col, data = dataOrig, target = target)
| min | Q1 | Median | Mean | Q3 | SD | Sk | Ck | |
|---|---|---|---|---|---|---|---|---|
| Churn | ||||||||
| No | 0.0 | 164.5 | 199.6 | 199.043298 | 233.20 | 50.292175 | -0.043140 | 0.032215 |
| Yes | 70.9 | 177.1 | 211.3 | 212.410145 | 249.45 | 51.728910 | 0.033129 | -0.103768 |
# Definindo o nome da variável a ser analisada.
col = 'Total_eve_calls'
# Definindo o nome da variável Target.
target = 'Churn'
# Definindo a descrição da variável nos gráficos.
label = 'Total_eve_calls'
# Capturando variáveis especificadas do Dataset.
data = dataOrig[[col, target]]
# Criando uma variável count para contabilizar as ocorrências de cada registro.
data['count'] = 1
# Agrupando dados e contabilizando o número de ocorrências.
data = data.groupby(by = [target, col]).sum()
# Reorganizando DataFrame.
data = data.reset_index()
# Plotando um gráfico de histograma para a variável especificada.
plotHist (
data = dataOrig[[col, target]],
title = 'Histograma para a variável ' + col,
xaxis = label,
yaxis = 'Frequência Absoluta',
col = col,
target = target,
groups = True
)
# Plotando um gráfico de boxplot para a variável especificada.
plotBoxplot (
data = dataOrig[[col, target]],
title = 'Boxplot para a variável ' + col,
yaxis = label,
xaxis = target.capitalize(),
col = col,
target = target,
kind = 'groups'
)
# Calculando algumas estatísticas para a variável especificada.
varStats(col = col, data = dataOrig, target = target)
| min | Q1 | Median | Mean | Q3 | SD | Sk | Ck | |
|---|---|---|---|---|---|---|---|---|
| Churn | ||||||||
| No | 0 | 87.0 | 100 | 100.038596 | 114.0 | 19.958414 | -0.069217 | 0.246968 |
| Yes | 48 | 87.0 | 101 | 100.561077 | 114.0 | 19.724711 | 0.029856 | -0.073037 |
# Definindo o nome da variável a ser analisada.
col = 'Total_eve_charge'
# Definindo o nome da variável Target.
target = 'Churn'
# Definindo a descrição da variável nos gráficos.
label = 'Total_eve_charge'
# Capturando variáveis especificadas do Dataset.
data = dataOrig[[col, target]]
# Criando uma variável count para contabilizar as ocorrências de cada registro.
data['count'] = 1
# Agrupando dados e contabilizando o número de ocorrências.
data = data.groupby(by = [target, col]).sum()
# Reorganizando DataFrame.
data = data.reset_index()
# Plotando um gráfico de histograma para a variável especificada.
plotHist (
data = dataOrig[[col, target]],
title = 'Histograma para a variável ' + col,
xaxis = label,
yaxis = 'Frequência Absoluta',
col = col,
target = target,
groups = True
)
# Plotando um gráfico de boxplot para a variável especificada.
plotBoxplot (
data = dataOrig[[col, target]],
title = 'Boxplot para a variável ' + col,
yaxis = label,
xaxis = target.capitalize(),
col = col,
target = target,
kind = 'groups'
)
# Calculando algumas estatísticas para a variável especificada.
varStats(col = col, data = dataOrig, target = target)
| min | Q1 | Median | Mean | Q3 | SD | Sk | Ck | |
|---|---|---|---|---|---|---|---|---|
| Churn | ||||||||
| No | 0.00 | 13.980 | 16.97 | 16.918909 | 19.820 | 4.274863 | -0.043103 | 0.032068 |
| Yes | 6.03 | 15.055 | 17.96 | 18.054969 | 21.205 | 4.396762 | 0.033144 | -0.103840 |
# Definindo o nome da variável a ser analisada.
col = 'Total_night_minutes'
# Definindo o nome da variável Target.
target = 'Churn'
# Definindo a descrição da variável nos gráficos.
label = 'Total_night_minutes'
# Capturando variáveis especificadas do Dataset.
data = dataOrig[[col, target]]
# Criando uma variável count para contabilizar as ocorrências de cada registro.
data['count'] = 1
# Agrupando dados e contabilizando o número de ocorrências.
data = data.groupby(by = [target, col]).sum()
# Reorganizando DataFrame.
data = data.reset_index()
# Plotando um gráfico de histograma para a variável especificada.
plotHist (
data = dataOrig[[col, target]],
title = 'Histograma para a variável ' + col,
xaxis = label,
yaxis = 'Frequência Absoluta',
col = col,
target = target,
groups = True
)
# Plotando um gráfico de boxplot para a variável especificada.
plotBoxplot (
data = dataOrig[[col, target]],
title = 'Boxplot para a variável ' + col,
yaxis = label,
xaxis = target.capitalize(),
col = col,
target = target,
kind = 'groups'
)
# Calculando algumas estatísticas para a variável especificada.
varStats(col = col, data = dataOrig, target = target)
| min | Q1 | Median | Mean | Q3 | SD | Sk | Ck | |
|---|---|---|---|---|---|---|---|---|
| Churn | ||||||||
| No | 23.2 | 165.90 | 200.25 | 200.133193 | 234.90 | 51.105032 | 0.017230 | 0.097274 |
| Yes | 47.4 | 171.25 | 204.80 | 205.231677 | 239.85 | 47.132825 | -0.005073 | -0.089390 |
# Definindo o nome da variável a ser analisada.
col = 'Total_night_calls'
# Definindo o nome da variável Target.
target = 'Churn'
# Definindo a descrição da variável nos gráficos.
label = 'Total_night_calls'
# Capturando variáveis especificadas do Dataset.
data = dataOrig[[col, target]]
# Criando uma variável count para contabilizar as ocorrências de cada registro.
data['count'] = 1
# Agrupando dados e contabilizando o número de ocorrências.
data = data.groupby(by = [target, col]).sum()
# Reorganizando DataFrame.
data = data.reset_index()
# Plotando um gráfico de histograma para a variável especificada.
plotHist (
data = dataOrig[[col, target]],
title = 'Histograma para a variável ' + col,
xaxis = label,
yaxis = 'Frequência Absoluta',
col = col,
target = target,
groups = True
)
# Plotando um gráfico de boxplot para a variável especificada.
plotBoxplot (
data = dataOrig[[col, target]],
title = 'Boxplot para a variável ' + col,
yaxis = label,
xaxis = target.capitalize(),
col = col,
target = target,
kind = 'groups'
)
# Calculando algumas estatísticas para a variável especificada.
varStats(col = col, data = dataOrig, target = target)
| min | Q1 | Median | Mean | Q3 | SD | Sk | Ck | |
|---|---|---|---|---|---|---|---|---|
| Churn | ||||||||
| No | 33 | 87.0 | 100 | 100.058246 | 113.0 | 19.506246 | 0.026949 | -0.018217 |
| Yes | 49 | 85.0 | 100 | 100.399586 | 115.0 | 19.950659 | 0.061494 | -0.380671 |
# Definindo o nome da variável a ser analisada.
col = 'Total_night_charge'
# Definindo o nome da variável Target.
target = 'Churn'
# Definindo a descrição da variável nos gráficos.
label = 'Total_night_charge'
# Capturando variáveis especificadas do Dataset.
data = dataOrig[[col, target]]
# Criando uma variável count para contabilizar as ocorrências de cada registro.
data['count'] = 1
# Agrupando dados e contabilizando o número de ocorrências.
data = data.groupby(by = [target, col]).sum()
# Reorganizando DataFrame.
data = data.reset_index()
# Plotando um gráfico de histograma para a variável especificada.
plotHist (
data = dataOrig[[col, target]],
title = 'Histograma para a variável ' + col,
xaxis = label,
yaxis = 'Frequência Absoluta',
col = col,
target = target,
groups = True
)
# Plotando um gráfico de boxplot para a variável especificada.
plotBoxplot (
data = dataOrig[[col, target]],
title = 'Boxplot para a variável ' + col,
yaxis = label,
xaxis = target.capitalize(),
col = col,
target = target,
kind = 'groups'
)
# Calculando algumas estatísticas para a variável especificada.
varStats(col = col, data = dataOrig, target = target)
| min | Q1 | Median | Mean | Q3 | SD | Sk | Ck | |
|---|---|---|---|---|---|---|---|---|
| Churn | ||||||||
| No | 1.04 | 7.470 | 9.01 | 9.006074 | 10.570 | 2.299768 | 0.017240 | 0.097067 |
| Yes | 2.13 | 7.705 | 9.22 | 9.235528 | 10.795 | 2.121081 | -0.005464 | -0.088868 |
# Definindo o nome da variável a ser analisada.
col = 'Total_intl_minutes'
# Definindo o nome da variável Target.
target = 'Churn'
# Definindo a descrição da variável nos gráficos.
label = 'Total_intl_minutes'
# Capturando variáveis especificadas do Dataset.
data = dataOrig[[col, target]]
# Criando uma variável count para contabilizar as ocorrências de cada registro.
data['count'] = 1
# Agrupando dados e contabilizando o número de ocorrências.
data = data.groupby(by = [target, col]).sum()
# Reorganizando DataFrame.
data = data.reset_index()
# Plotando um gráfico de histograma para a variável especificada.
plotHist (
data = dataOrig[[col, target]],
title = 'Histograma para a variável ' + col,
xaxis = label,
yaxis = 'Frequência Absoluta',
col = col,
target = target,
groups = True
)
# Plotando um gráfico de boxplot para a variável especificada.
plotBoxplot (
data = dataOrig[[col, target]],
title = 'Boxplot para a variável ' + col,
yaxis = label,
xaxis = target.capitalize(),
col = col,
target = target,
kind = 'groups'
)
# Calculando algumas estatísticas para a variável especificada.
varStats(col = col, data = dataOrig, target = target)
| min | Q1 | Median | Mean | Q3 | SD | Sk | Ck | |
|---|---|---|---|---|---|---|---|---|
| Churn | ||||||||
| No | 0.0 | 8.4 | 10.2 | 10.158877 | 12.0 | 2.784489 | -0.293780 | 0.683283 |
| Yes | 2.0 | 8.8 | 10.6 | 10.700000 | 12.8 | 2.793190 | 0.021392 | -0.012325 |
# Definindo o nome da variável a ser analisada.
col = 'Total_intl_calls'
# Definindo o nome da variável Target.
target = 'Churn'
# Definindo a descrição da variável nos gráficos.
label = 'Total_intl_calls'
# Capturando variáveis especificadas do Dataset.
data = dataOrig[[col, target]]
# Criando uma variável count para contabilizar as ocorrências de cada registro.
data['count'] = 1
# Agrupando dados e contabilizando o número de ocorrências.
data = data.groupby(by = [target, col]).sum()
# Reorganizando DataFrame.
data = data.reset_index()
# Plotando um gráfico de histograma para a variável especificada.
plotHist (
data = dataOrig[[col, target]],
title = 'Histograma para a variável ' + col,
xaxis = label,
yaxis = 'Frequência Absoluta',
col = col,
target = target,
groups = True
)
# Plotando um gráfico de boxplot para a variável especificada.
plotBoxplot (
data = dataOrig[[col, target]],
title = 'Boxplot para a variável ' + col,
yaxis = label,
xaxis = target.capitalize(),
col = col,
target = target,
kind = 'groups'
)
# Calculando algumas estatísticas para a variável especificada.
varStats(col = col, data = dataOrig, target = target)
| min | Q1 | Median | Mean | Q3 | SD | Sk | Ck | |
|---|---|---|---|---|---|---|---|---|
| Churn | ||||||||
| No | 0 | 3.0 | 4 | 4.532982 | 6.0 | 2.441984 | 1.259044 | 2.798436 |
| Yes | 1 | 2.0 | 4 | 4.163561 | 5.0 | 2.551575 | 1.714231 | 4.821751 |
# Definindo o nome da variável a ser analisada.
col = 'Total_intl_charge'
# Definindo o nome da variável Target.
target = 'Churn'
# Definindo a descrição da variável nos gráficos.
label = 'Total_intl_charge'
# Capturando variáveis especificadas do Dataset.
data = dataOrig[[col, target]]
# Criando uma variável count para contabilizar as ocorrências de cada registro.
data['count'] = 1
# Agrupando dados e contabilizando o número de ocorrências.
data = data.groupby(by = [target, col]).sum()
# Reorganizando DataFrame.
data = data.reset_index()
# Plotando um gráfico de histograma para a variável especificada.
plotHist (
data = dataOrig[[col, target]],
title = 'Histograma para a variável ' + col,
xaxis = label,
yaxis = 'Frequência Absoluta',
col = col,
target = target,
groups = True
)
# Plotando um gráfico de boxplot para a variável especificada.
plotBoxplot (
data = dataOrig[[col, target]],
title = 'Boxplot para a variável ' + col,
yaxis = label,
xaxis = target.capitalize(),
col = col,
target = target,
kind = 'groups'
)
# Calculando algumas estatísticas para a variável especificada.
varStats(col = col, data = dataOrig, target = target)
| min | Q1 | Median | Mean | Q3 | SD | Sk | Ck | |
|---|---|---|---|---|---|---|---|---|
| Churn | ||||||||
| No | 0.00 | 2.27 | 2.75 | 2.743404 | 3.24 | 0.751784 | -0.293902 | 0.683996 |
| Yes | 0.54 | 2.38 | 2.86 | 2.889545 | 3.46 | 0.754152 | 0.021009 | -0.013370 |
# Definindo o nome da variável a ser analisada.
col = 'Customer_service_calls'
# Definindo o nome da variável Target.
target = 'Churn'
# Definindo a descrição da variável nos gráficos.
label = 'Customer_service_calls'
# Capturando variáveis especificadas do Dataset.
data = dataOrig[[col, target]]
# Criando uma variável count para contabilizar as ocorrências de cada registro.
data['count'] = 1
# Agrupando dados e contabilizando o número de ocorrências.
data = data.groupby(by = [target, col]).sum()
# Reorganizando DataFrame.
data = data.reset_index()
# Plotando um gráfico de histograma para a variável especificada.
plotHist (
data = dataOrig[[col, target]],
title = 'Histograma para a variável ' + col,
xaxis = label,
yaxis = 'Frequência Absoluta',
col = col,
target = target,
groups = True
)
# Plotando um gráfico de boxplot para a variável especificada.
plotBoxplot (
data = dataOrig[[col, target]],
title = 'Boxplot para a variável ' + col,
yaxis = label,
xaxis = target.capitalize(),
col = col,
target = target,
kind = 'groups'
)
# Calculando algumas estatísticas para a variável especificada.
varStats(col = col, data = dataOrig, target = target)
| min | Q1 | Median | Mean | Q3 | SD | Sk | Ck | |
|---|---|---|---|---|---|---|---|---|
| Churn | ||||||||
| No | 0 | 1.0 | 1 | 1.449825 | 2.0 | 1.163883 | 0.886801 | 1.210349 |
| Yes | 0 | 1.0 | 2 | 2.229814 | 4.0 | 1.853275 | 0.703604 | -0.109937 |
# Definindo o nome da variável a ser analisada.
col = 'Churn'
# Definindo a descrição da variável nos gráficos.
label = 'Churn'
# Contabilizando a frequência absoluta, de cada categoria presente na variável especificada.
dataCounts = dataOrig[col].value_counts()
# Plotando um gráfico de barras para a variável especificada.
plotBar (
data = dataCounts,
title = 'Frequência absoluta das categorias do target ' + col,
yaxis = 'Frequência Absoluta',
xaxis = label
)
# Plotando um gráfico de pizza para a variável especificada.
plotPie (
data = dataCounts,
title = 'Frequência relativa das categorias do target ' + col
)
Observa-se uma desproporção entre o número de clientes que efetuaram o Churn (Yes / 14,5%), para aqueles que não realizaram (No / 85,5%).
Para investigação da correlação existente entre as variáveis é primeiro necessário um processamento das variáveis categóricas no conjunto de dados.
Para a codificação de variáveis categóricas são criadas variáveis dummies segundo duas técnicas:
# Codificando as variáveis especificadas usando a técnica dummy encoding
dataOrigTf_dummy = pd.get_dummies(data=dataOrig, columns = ['Area_code', 'International_plan', 'Voice_mail_plan', 'Churn'],
drop_first=True )
dataOrigTf_dummy.info()
<class 'pandas.core.frame.DataFrame'> Int64Index: 3333 entries, 0 to 666 Data columns (total 22 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 State 3333 non-null category 1 Account_length 3333 non-null int64 2 Number_vmail_messages 3333 non-null int64 3 Total_day_minutes 3333 non-null float64 4 Total_day_calls 3333 non-null int64 5 Total_day_charge 3333 non-null float64 6 Total_eve_minutes 3333 non-null float64 7 Total_eve_calls 3333 non-null int64 8 Total_eve_charge 3333 non-null float64 9 Total_night_minutes 3333 non-null float64 10 Total_night_calls 3333 non-null int64 11 Total_night_charge 3333 non-null float64 12 Total_intl_minutes 3333 non-null float64 13 Total_intl_calls 3333 non-null int64 14 Total_intl_charge 3333 non-null float64 15 Customer_service_calls 3333 non-null int64 16 Train 3333 non-null int64 17 Area_code_415 3333 non-null uint8 18 Area_code_510 3333 non-null uint8 19 International_plan_Yes 3333 non-null uint8 20 Voice_mail_plan_Yes 3333 non-null uint8 21 Churn_Yes 3333 non-null uint8 dtypes: category(1), float64(8), int64(8), uint8(5) memory usage: 465.1 KB
# Visualização das primeiras linhas do dataframe transformado
dataOrigTf_dummy.head()
| State | Account_length | Number_vmail_messages | Total_day_minutes | Total_day_calls | Total_day_charge | Total_eve_minutes | Total_eve_calls | Total_eve_charge | Total_night_minutes | ... | Total_intl_minutes | Total_intl_calls | Total_intl_charge | Customer_service_calls | Train | Area_code_415 | Area_code_510 | International_plan_Yes | Voice_mail_plan_Yes | Churn_Yes | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | KS | 128 | 25 | 265.1 | 110 | 45.07 | 197.4 | 99 | 16.78 | 244.7 | ... | 10.0 | 3 | 2.70 | 1 | 1 | 1 | 0 | 0 | 1 | 0 |
| 1 | OH | 107 | 26 | 161.6 | 123 | 27.47 | 195.5 | 103 | 16.62 | 254.4 | ... | 13.7 | 3 | 3.70 | 1 | 1 | 1 | 0 | 0 | 1 | 0 |
| 2 | NJ | 137 | 0 | 243.4 | 114 | 41.38 | 121.2 | 110 | 10.30 | 162.6 | ... | 12.2 | 5 | 3.29 | 0 | 1 | 1 | 0 | 0 | 0 | 0 |
| 3 | OH | 84 | 0 | 299.4 | 71 | 50.90 | 61.9 | 88 | 5.26 | 196.9 | ... | 6.6 | 7 | 1.78 | 2 | 1 | 0 | 0 | 1 | 0 | 0 |
| 4 | OK | 75 | 0 | 166.7 | 113 | 28.34 | 148.3 | 122 | 12.61 | 186.9 | ... | 10.1 | 3 | 2.73 | 3 | 1 | 1 | 0 | 1 | 0 | 0 |
5 rows × 22 columns
Novas colunas codificadas foram criadas em substituição as variáveis categóricas 'Area_code', 'International_plan', 'Voice_mail_plan', 'Churn'.
Na codificação binária, as categorias possíveis de uma variável são primeiramente convertidas a um valor ordinal e em seguida convertidas em suas formas binárias, ou seja, na base 2. Em sequência são criadas um número de variáveis codificadas para armazer a codificação binária distribuida nas colunas, representando cada valor possível da variável categórica.
Essa abordagem foi adotada para lidar com a variável State, pois a feature apresenta 51 valores possíveis.
#Criando um objeto para a codificação binária
encoder = ce.BinaryEncoder(cols=['State'],return_df=True)
# Tranformação da variáveis State para uma forma binária
dataOrigTf_bin = encoder.fit_transform(dataOrigTf_dummy)
# Visualização das primeiras linhas do dataframe
dataOrigTf_bin.head()
| State_0 | State_1 | State_2 | State_3 | State_4 | State_5 | State_6 | Account_length | Number_vmail_messages | Total_day_minutes | ... | Total_intl_minutes | Total_intl_calls | Total_intl_charge | Customer_service_calls | Train | Area_code_415 | Area_code_510 | International_plan_Yes | Voice_mail_plan_Yes | Churn_Yes | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 128 | 25 | 265.1 | ... | 10.0 | 3 | 2.70 | 1 | 1 | 1 | 0 | 0 | 1 | 0 |
| 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 107 | 26 | 161.6 | ... | 13.7 | 3 | 3.70 | 1 | 1 | 1 | 0 | 0 | 1 | 0 |
| 2 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 137 | 0 | 243.4 | ... | 12.2 | 5 | 3.29 | 0 | 1 | 1 | 0 | 0 | 0 | 0 |
| 3 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 84 | 0 | 299.4 | ... | 6.6 | 7 | 1.78 | 2 | 1 | 0 | 0 | 1 | 0 | 0 |
| 4 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 75 | 0 | 166.7 | ... | 10.1 | 3 | 2.73 | 3 | 1 | 1 | 0 | 1 | 0 | 0 |
5 rows × 28 columns
# Visualização de informações do dataframe
dataOrigTf_bin.info()
<class 'pandas.core.frame.DataFrame'> Int64Index: 3333 entries, 0 to 666 Data columns (total 28 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 State_0 3333 non-null int64 1 State_1 3333 non-null int64 2 State_2 3333 non-null int64 3 State_3 3333 non-null int64 4 State_4 3333 non-null int64 5 State_5 3333 non-null int64 6 State_6 3333 non-null int64 7 Account_length 3333 non-null int64 8 Number_vmail_messages 3333 non-null int64 9 Total_day_minutes 3333 non-null float64 10 Total_day_calls 3333 non-null int64 11 Total_day_charge 3333 non-null float64 12 Total_eve_minutes 3333 non-null float64 13 Total_eve_calls 3333 non-null int64 14 Total_eve_charge 3333 non-null float64 15 Total_night_minutes 3333 non-null float64 16 Total_night_calls 3333 non-null int64 17 Total_night_charge 3333 non-null float64 18 Total_intl_minutes 3333 non-null float64 19 Total_intl_calls 3333 non-null int64 20 Total_intl_charge 3333 non-null float64 21 Customer_service_calls 3333 non-null int64 22 Train 3333 non-null int64 23 Area_code_415 3333 non-null uint8 24 Area_code_510 3333 non-null uint8 25 International_plan_Yes 3333 non-null uint8 26 Voice_mail_plan_Yes 3333 non-null uint8 27 Churn_Yes 3333 non-null uint8 dtypes: float64(8), int64(15), uint8(5) memory usage: 641.2 KB
Observa-se:
# Armazenado o dataframe transformado após as codificações
dataOrigTf = dataOrigTf_bin
Para a análise da correlação entre as variáveis, não é do interesse analisar a variável criada 'Train' que identifica a origem dos dados, assim a coluna é excluída da análise.
# Apresentando a correlação entre variáveis
dataOrigTf_corr = dataOrigTf.drop('Train', axis=1).corr()
dataOrigTf_corr
| State_0 | State_1 | State_2 | State_3 | State_4 | State_5 | State_6 | Account_length | Number_vmail_messages | Total_day_minutes | ... | Total_night_charge | Total_intl_minutes | Total_intl_calls | Total_intl_charge | Customer_service_calls | Area_code_415 | Area_code_510 | International_plan_Yes | Voice_mail_plan_Yes | Churn_Yes | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| State_0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
| State_1 | NaN | 1.000000 | -0.302285 | -0.118624 | -0.101739 | 0.005837 | 0.011780 | -0.001592 | -0.001686 | -0.008648 | ... | 0.001613 | -0.014043 | -0.018547 | -0.014074 | -0.013363 | -0.001449 | -0.000416 | 0.007071 | -0.003001 | 0.042452 |
| State_2 | NaN | -0.302285 | 1.000000 | -0.102746 | -0.096973 | 0.008285 | -0.022850 | 0.024301 | 0.005948 | 0.009151 | ... | -0.010186 | -0.018492 | -0.019604 | -0.018482 | 0.008008 | -0.006435 | -0.015389 | 0.012487 | -0.000704 | -0.042256 |
| State_3 | NaN | -0.118624 | -0.102746 | 1.000000 | 0.062421 | -0.051701 | -0.017566 | -0.037296 | -0.009565 | -0.022514 | ... | 0.004387 | 0.014865 | -0.008295 | 0.014821 | 0.048415 | 0.009057 | 0.036300 | -0.015501 | -0.003039 | 0.008985 |
| State_4 | NaN | -0.101739 | -0.096973 | 0.062421 | 1.000000 | -0.055786 | -0.007565 | 0.001188 | -0.039284 | -0.017775 | ... | 0.023893 | -0.002586 | 0.018015 | -0.002497 | -0.000692 | -0.001081 | -0.009729 | 0.011597 | -0.034844 | 0.001371 |
| State_5 | NaN | 0.005837 | 0.008285 | -0.051701 | -0.055786 | 1.000000 | -0.012099 | -0.024430 | 0.009630 | 0.006760 | ... | 0.035568 | -0.000824 | 0.011439 | -0.000788 | 0.005150 | 0.002032 | -0.034334 | -0.016027 | 0.000757 | 0.020271 |
| State_6 | NaN | 0.011780 | -0.022850 | -0.017566 | -0.007565 | -0.012099 | 1.000000 | -0.018710 | -0.022296 | 0.008660 | ... | 0.015508 | -0.005899 | 0.001331 | -0.005983 | 0.019887 | 0.024451 | -0.014784 | 0.008433 | -0.020855 | 0.026428 |
| Account_length | NaN | -0.001592 | 0.024301 | -0.037296 | 0.001188 | -0.024430 | -0.018710 | 1.000000 | -0.004628 | 0.006216 | ... | -0.008960 | 0.009514 | 0.020661 | 0.009546 | -0.003796 | 0.000102 | -0.011931 | 0.024735 | 0.002918 | 0.016541 |
| Number_vmail_messages | NaN | -0.001686 | 0.005948 | -0.009565 | -0.039284 | 0.009630 | -0.022296 | -0.004628 | 1.000000 | 0.000778 | ... | 0.007663 | 0.002856 | 0.013957 | 0.002884 | -0.013263 | 0.018772 | -0.003391 | 0.008745 | 0.956927 | -0.089728 |
| Total_day_minutes | NaN | -0.008648 | 0.009151 | -0.022514 | -0.017775 | 0.006760 | 0.008660 | 0.006216 | 0.000778 | 1.000000 | ... | 0.004300 | -0.010155 | 0.008033 | -0.010092 | -0.013423 | 0.033145 | -0.010525 | 0.049396 | -0.001684 | 0.205151 |
| Total_day_calls | NaN | -0.004929 | -0.023634 | 0.013686 | 0.032456 | 0.009127 | -0.023660 | 0.038470 | -0.009548 | 0.006750 | ... | 0.022927 | 0.021565 | 0.004574 | 0.021666 | -0.018942 | 0.006968 | -0.009778 | 0.003755 | -0.011086 | 0.018459 |
| Total_day_charge | NaN | -0.008649 | 0.009149 | -0.022503 | -0.017783 | 0.006764 | 0.008662 | 0.006214 | 0.000776 | 1.000000 | ... | 0.004301 | -0.010157 | 0.008032 | -0.010094 | -0.013427 | 0.033150 | -0.010526 | 0.049398 | -0.001686 | 0.205151 |
| Total_eve_minutes | NaN | 0.009422 | -0.011560 | -0.007567 | 0.027084 | 0.034890 | 0.001853 | -0.006757 | 0.017562 | 0.007043 | ... | -0.012593 | -0.011035 | 0.002541 | -0.011067 | -0.012985 | -0.006429 | 0.003933 | 0.019100 | 0.021545 | 0.092796 |
| Total_eve_calls | NaN | 0.022399 | -0.003385 | -0.028684 | -0.026203 | 0.007212 | -0.007757 | 0.019260 | -0.005864 | 0.015769 | ... | -0.002056 | 0.008703 | 0.017434 | 0.008674 | 0.002423 | 0.019425 | -0.012906 | 0.006114 | -0.006444 | 0.009233 |
| Total_eve_charge | NaN | 0.009420 | -0.011574 | -0.007563 | 0.027096 | 0.034895 | 0.001849 | -0.006745 | 0.017578 | 0.007029 | ... | -0.012601 | -0.011043 | 0.002541 | -0.011074 | -0.012987 | -0.006445 | 0.003960 | 0.019106 | 0.021559 | 0.092786 |
| Total_night_minutes | NaN | 0.001614 | -0.010201 | 0.004382 | 0.023918 | 0.035562 | 0.015516 | -0.008955 | 0.007681 | 0.004323 | ... | 0.999999 | -0.015207 | -0.012353 | -0.015180 | -0.009288 | 0.022891 | -0.007381 | -0.028905 | 0.006079 | 0.035493 |
| Total_night_calls | NaN | 0.003381 | 0.005495 | -0.002209 | 0.007246 | -0.017688 | 0.006558 | -0.013176 | 0.007123 | 0.022972 | ... | 0.011188 | -0.013605 | 0.000305 | -0.013630 | -0.012802 | 0.014744 | 0.014640 | 0.012451 | 0.015553 | 0.006141 |
| Total_night_charge | NaN | 0.001613 | -0.010186 | 0.004387 | 0.023893 | 0.035568 | 0.015508 | -0.008960 | 0.007663 | 0.004300 | ... | 1.000000 | -0.015214 | -0.012329 | -0.015186 | -0.009277 | 0.022900 | -0.007402 | -0.028913 | 0.006064 | 0.035496 |
| Total_intl_minutes | NaN | -0.014043 | -0.018492 | 0.014865 | -0.002586 | -0.000824 | -0.005899 | 0.009514 | 0.002856 | -0.010155 | ... | -0.015214 | 1.000000 | 0.032304 | 0.999993 | -0.009640 | 0.037766 | -0.020480 | 0.045871 | -0.001318 | 0.068239 |
| Total_intl_calls | NaN | -0.018547 | -0.019604 | -0.008295 | 0.018015 | 0.011439 | 0.001331 | 0.020661 | 0.013957 | 0.008033 | ... | -0.012329 | 0.032304 | 1.000000 | 0.032372 | -0.017561 | 0.033289 | -0.025761 | 0.017366 | 0.007618 | -0.052844 |
| Total_intl_charge | NaN | -0.014074 | -0.018482 | 0.014821 | -0.002497 | -0.000788 | -0.005983 | 0.009546 | 0.002884 | -0.010092 | ... | -0.015186 | 0.999993 | 0.032372 | 1.000000 | -0.009675 | 0.037786 | -0.020583 | 0.045780 | -0.001276 | 0.068259 |
| Customer_service_calls | NaN | -0.013363 | 0.008008 | 0.048415 | -0.000692 | 0.005150 | 0.019887 | -0.003796 | -0.013263 | -0.013423 | ... | -0.009277 | -0.009640 | -0.017561 | -0.009675 | 1.000000 | -0.006628 | 0.026900 | -0.024522 | -0.017824 | 0.208750 |
| Area_code_415 | NaN | -0.001449 | -0.006435 | 0.009057 | -0.001081 | 0.002032 | 0.024451 | 0.000102 | 0.018772 | 0.033145 | ... | 0.022900 | 0.037766 | 0.033289 | 0.037786 | -0.006628 | 1.000000 | -0.576476 | -0.021066 | 0.017682 | -0.006535 |
| Area_code_510 | NaN | -0.000416 | -0.015389 | 0.036300 | -0.009729 | -0.034334 | -0.014784 | -0.011931 | -0.003391 | -0.010525 | ... | -0.007402 | -0.020480 | -0.025761 | -0.020583 | 0.026900 | -0.576476 | 1.000000 | 0.048109 | -0.002112 | 0.006423 |
| International_plan_Yes | NaN | 0.007071 | 0.012487 | -0.015501 | 0.011597 | -0.016027 | 0.008433 | 0.024735 | 0.008745 | 0.049396 | ... | -0.028913 | 0.045871 | 0.017366 | 0.045780 | -0.024522 | -0.021066 | 0.048109 | 1.000000 | 0.006006 | 0.259852 |
| Voice_mail_plan_Yes | NaN | -0.003001 | -0.000704 | -0.003039 | -0.034844 | 0.000757 | -0.020855 | 0.002918 | 0.956927 | -0.001684 | ... | 0.006064 | -0.001318 | 0.007618 | -0.001276 | -0.017824 | 0.017682 | -0.002112 | 0.006006 | 1.000000 | -0.102148 |
| Churn_Yes | NaN | 0.042452 | -0.042256 | 0.008985 | 0.001371 | 0.020271 | 0.026428 | 0.016541 | -0.089728 | 0.205151 | ... | 0.035496 | 0.068239 | -0.052844 | 0.068259 | 0.208750 | -0.006535 | 0.006423 | 0.259852 | -0.102148 | 1.000000 |
27 rows × 27 columns
A variável State_0 representa o primeiro caracter da representação binária, sendo composta apenas do número 0. Assim, ao processarmos a correlação entre as variáveis, essa gera valores NaN que serão desconsiderados ao plotarmos a matriz de correlação em forma de gráfico.
# Filtrando apenas o triângulo superior da tabela de correlação
dataOrigTf_corr_diag_princ = dataOrigTf_corr.where(np.tril(np.ones(dataOrigTf_corr.shape), k=-1).astype(np.bool))
# Apresentando um gráfico de calor com as correlações entre todas as variáveis
plt.figure(figsize=(18,18))
sns.heatmap(data = dataOrigTf_corr_diag_princ,
annot = True,
cmap = 'Blues',
vmax = .3,
linewidths = 0.5,
square = True
)
<AxesSubplot:>
Com base no gráfico acima, observa-se:
Estabele-se um therehold de 0.9 e qualquer feature com valor absoluto maior ou igual a 0.9 será excluída do conjunto de dados para as análises posteriores.
# Obtendo as colunas com alta correlação positiva ou negativa (com threshold de correlação {>=0.90})
threshold = 0.9
to_drop = [column for column in dataOrigTf_corr_diag_princ.columns if any(abs(dataOrigTf_corr_diag_princ[column]) >= threshold)]
# Print das variáveis a serem excluídas
print(to_drop)
['Number_vmail_messages', 'Total_day_minutes', 'Total_eve_minutes', 'Total_night_minutes', 'Total_intl_minutes']
# Excluindo as colunas com alta correlação
dataOrigTf_dropcor = dataOrigTf.drop(to_drop, axis=1)
dataOrigTf_dropcor.head()
| State_0 | State_1 | State_2 | State_3 | State_4 | State_5 | State_6 | Account_length | Total_day_calls | Total_day_charge | ... | Total_night_charge | Total_intl_calls | Total_intl_charge | Customer_service_calls | Train | Area_code_415 | Area_code_510 | International_plan_Yes | Voice_mail_plan_Yes | Churn_Yes | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 128 | 110 | 45.07 | ... | 11.01 | 3 | 2.70 | 1 | 1 | 1 | 0 | 0 | 1 | 0 |
| 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 107 | 123 | 27.47 | ... | 11.45 | 3 | 3.70 | 1 | 1 | 1 | 0 | 0 | 1 | 0 |
| 2 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 137 | 114 | 41.38 | ... | 7.32 | 5 | 3.29 | 0 | 1 | 1 | 0 | 0 | 0 | 0 |
| 3 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 84 | 71 | 50.90 | ... | 8.86 | 7 | 1.78 | 2 | 1 | 0 | 0 | 1 | 0 | 0 |
| 4 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 75 | 113 | 28.34 | ... | 8.41 | 3 | 2.73 | 3 | 1 | 1 | 0 | 1 | 0 | 0 |
5 rows × 23 columns
print(f'Threshold utilizado: {threshold}')
print(f'Quantidade de colunas no dataset original: {dataOrigTf.shape[1]}')
print(f'Quantidade de colunas no dataset resultante: {dataOrigTf_dropcor.shape[1]}')
Threshold utilizado: 0.9 Quantidade de colunas no dataset original: 28 Quantidade de colunas no dataset resultante: 23
dataOrigTf_scaled = dataOrigTf_dropcor
# Colunas para serem normalizadas ( colunas de variáveis quantitativas)
column_to_scale = ['Account_length', 'Total_day_calls', 'Total_day_charge',
'Total_eve_calls', 'Total_eve_charge', 'Total_night_calls', 'Total_night_charge',
'Total_intl_calls', 'Total_intl_charge', 'Customer_service_calls']
# Criando um objeto da classe MinMaxScaler().
scaler = MinMaxScaler()
# Normalização coluna a coluna
for col in column_to_scale:
featureTransformed = scaler.fit_transform(dataOrigTf_dropcor[[col]])
dataOrigTf_scaled[col] = pd.DataFrame(featureTransformed)
dataOrigTf_scaled
| State_0 | State_1 | State_2 | State_3 | State_4 | State_5 | State_6 | Account_length | Total_day_calls | Total_day_charge | ... | Total_night_charge | Total_intl_calls | Total_intl_charge | Customer_service_calls | Train | Area_code_415 | Area_code_510 | International_plan_Yes | Voice_mail_plan_Yes | Churn_Yes | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0.524793 | 0.666667 | 0.755701 | ... | 0.595935 | 0.15 | 0.500000 | 0.111111 | 1 | 1 | 0 | 0 | 1 | 0 |
| 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0.438017 | 0.745455 | 0.460597 | ... | 0.622236 | 0.15 | 0.685185 | 0.111111 | 1 | 1 | 0 | 0 | 1 | 0 |
| 2 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0.561983 | 0.690909 | 0.693830 | ... | 0.375374 | 0.25 | 0.609259 | 0.000000 | 1 | 1 | 0 | 0 | 0 | 0 |
| 3 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0.342975 | 0.430303 | 0.853454 | ... | 0.467424 | 0.35 | 0.329630 | 0.222222 | 1 | 0 | 0 | 1 | 0 | 0 |
| 4 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0.305785 | 0.684848 | 0.475184 | ... | 0.440526 | 0.15 | 0.505556 | 0.333333 | 1 | 1 | 0 | 1 | 0 | 0 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 662 | 0 | 0 | 1 | 1 | 1 | 0 | 0 | 0.359504 | 0.472727 | 0.625755 | ... | 0.444112 | 0.25 | 0.805556 | 0.111111 | 0 | 1 | 0 | 0 | 1 | 0 |
| 663 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0.454545 | 0.678788 | 0.283032 | ... | 0.543933 | 0.30 | 0.450000 | 0.333333 | 0 | 0 | 0 | 0 | 1 | 0 |
| 664 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | 0.314050 | 0.690909 | 0.681757 | ... | 0.370592 | 0.10 | 0.514815 | 0.555556 | 0 | 1 | 0 | 0 | 0 | 0 |
| 665 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0.272727 | 0.351515 | 0.344567 | ... | 0.193664 | 0.55 | 0.570370 | 0.222222 | 0 | 1 | 0 | 0 | 0 | 0 |
| 666 | 0 | 1 | 1 | 0 | 0 | 1 | 1 | 0.417355 | 0.490909 | 0.640510 | ... | 0.388524 | 0.30 | 0.790741 | 0.111111 | 0 | 0 | 1 | 1 | 0 | 0 |
3333 rows × 23 columns
# Visualização do resultado da normalização
dataOrigTf_scaled.describe()
| State_0 | State_1 | State_2 | State_3 | State_4 | State_5 | State_6 | Account_length | Total_day_calls | Total_day_charge | ... | Total_night_charge | Total_intl_calls | Total_intl_charge | Customer_service_calls | Train | Area_code_415 | Area_code_510 | International_plan_Yes | Voice_mail_plan_Yes | Churn_Yes | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| count | 3333.0 | 3333.000000 | 3333.000000 | 3333.000000 | 3333.000000 | 3333.000000 | 3333.000000 | 3333.000000 | 3333.000000 | 3333.000000 | ... | 3333.000000 | 3333.000000 | 3333.000000 | 3333.000000 | 3333.00000 | 3333.000000 | 3333.000000 | 3333.000000 | 3333.000000 | 3333.000000 |
| mean | 0.0 | 0.376538 | 0.374737 | 0.481848 | 0.486949 | 0.495050 | 0.510351 | 0.411323 | 0.607697 | 0.513314 | ... | 0.478297 | 0.223777 | 0.512320 | 0.173451 | 0.79988 | 0.496550 | 0.252025 | 0.096910 | 0.276628 | 0.144914 |
| std | 0.0 | 0.484590 | 0.484128 | 0.499745 | 0.499905 | 0.500051 | 0.499968 | 0.162682 | 0.120631 | 0.154007 | ... | 0.136268 | 0.123424 | 0.139772 | 0.145158 | 0.40015 | 0.500063 | 0.434241 | 0.295879 | 0.447398 | 0.352067 |
| min | 0.0 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | ... | 0.055589 | 0.000000 | 0.000000 | 0.000000 | 0.00000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 |
| 25% | 0.0 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.297521 | 0.527273 | 0.412810 | ... | 0.386730 | 0.150000 | 0.425926 | 0.111111 | 1.00000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 |
| 50% | 0.0 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 1.000000 | 0.409091 | 0.612121 | 0.517103 | ... | 0.478183 | 0.200000 | 0.509259 | 0.111111 | 1.00000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 |
| 75% | 0.0 | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 0.520661 | 0.690909 | 0.615694 | ... | 0.574417 | 0.300000 | 0.605556 | 0.222222 | 1.00000 | 1.000000 | 1.000000 | 0.000000 | 1.000000 | 0.000000 |
| max | 0.0 | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 0.969697 | 1.000000 | ... | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 1.00000 | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 1.000000 |
8 rows × 23 columns
RFE é uma técnica para seleção de atributos, que recursivamente remove os atributos e constrói o modelo com os atributos remanescentes. Esta técnica utiliza a acurácia do modelo para identificar os atributos que mais contribuem para prever a variável alvo.
# Separando a variável target das features
features = dataOrigTf_scaled.drop(['Train','Churn_Yes'], axis=1)
features.info()
<class 'pandas.core.frame.DataFrame'> Int64Index: 3333 entries, 0 to 666 Data columns (total 21 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 State_0 3333 non-null int64 1 State_1 3333 non-null int64 2 State_2 3333 non-null int64 3 State_3 3333 non-null int64 4 State_4 3333 non-null int64 5 State_5 3333 non-null int64 6 State_6 3333 non-null int64 7 Account_length 3333 non-null float64 8 Total_day_calls 3333 non-null float64 9 Total_day_charge 3333 non-null float64 10 Total_eve_calls 3333 non-null float64 11 Total_eve_charge 3333 non-null float64 12 Total_night_calls 3333 non-null float64 13 Total_night_charge 3333 non-null float64 14 Total_intl_calls 3333 non-null float64 15 Total_intl_charge 3333 non-null float64 16 Customer_service_calls 3333 non-null float64 17 Area_code_415 3333 non-null uint8 18 Area_code_510 3333 non-null uint8 19 International_plan_Yes 3333 non-null uint8 20 Voice_mail_plan_Yes 3333 non-null uint8 dtypes: float64(10), int64(7), uint8(4) memory usage: 481.7 KB
# Separando a variável target
target = dataOrigTf_scaled['Churn_Yes']
target
0 0
1 0
2 0
3 0
4 0
..
662 0
663 0
664 0
665 0
666 0
Name: Churn_Yes, Length: 3333, dtype: uint8
# Instanciando um objeto da classe RFE para selecionar as melhores variáveis preditoras, utilizando o algoritmo LogisticRegression.
modelo = LogisticRegression()
rfe = RFE (
estimator = modelo,
n_features_to_select = 10
)
# Capturando as 10 melhores variáveis preditoras.
rfeFit = rfe.fit (
X = features,
y = target
)
# Print dos resultados
print("Variáveis Preditoras:", features.columns)
print("Variáveis Selecionadas: %s" % rfeFit.support_)
print("Ranking dos Atributos: %s" % rfeFit.ranking_)
print("Número de Melhores Atributos: %d" % rfeFit.n_features_)
Variáveis Preditoras: Index(['State_0', 'State_1', 'State_2', 'State_3', 'State_4', 'State_5',
'State_6', 'Account_length', 'Total_day_calls', 'Total_day_charge',
'Total_eve_calls', 'Total_eve_charge', 'Total_night_calls',
'Total_night_charge', 'Total_intl_calls', 'Total_intl_charge',
'Customer_service_calls', 'Area_code_415', 'Area_code_510',
'International_plan_Yes', 'Voice_mail_plan_Yes'],
dtype='object')
Variáveis Selecionadas: [False False True False False False False False True True False True
False True True True True False False True True]
Ranking dos Atributos: [12 3 1 6 11 4 5 2 1 1 10 1 7 1 1 1 1 9 8 1 1]
Número de Melhores Atributos: 10
# Capturando o nome das variáveis preditoras.
bfRfe = features.columns[rfeFit.support_]
# Exibindo o nome das variáveis preditoras.
bfRfe
Index(['State_2', 'Total_day_calls', 'Total_day_charge', 'Total_eve_charge',
'Total_night_charge', 'Total_intl_calls', 'Total_intl_charge',
'Customer_service_calls', 'International_plan_Yes',
'Voice_mail_plan_Yes'],
dtype='object')
A amostragem em dados de treino e teste será recomposta conforme o dataset original fornecido e conforme as features selecionadas anteriormente.
# Separação dos conjuntos de dados em teste e treino conforme os dados originais
## Train = 1 (Treino)
## Train = 0 (Teste)
# Seleção dos dados de treino e das features selecionadas na etapa de feature selection
featuresTrain = dataOrigTf_scaled[dataOrigTf_scaled['Train']==1][list(bfRfe)]
featuresTrain
| State_2 | Total_day_calls | Total_day_charge | Total_eve_charge | Total_night_charge | Total_intl_calls | Total_intl_charge | Customer_service_calls | International_plan_Yes | Voice_mail_plan_Yes | |
|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0 | 0.666667 | 0.755701 | 0.542866 | 0.595935 | 0.15 | 0.500000 | 0.111111 | 0 | 1 |
| 1 | 0 | 0.745455 | 0.460597 | 0.537690 | 0.622236 | 0.15 | 0.685185 | 0.111111 | 0 | 1 |
| 2 | 0 | 0.690909 | 0.693830 | 0.333225 | 0.375374 | 0.25 | 0.609259 | 0.000000 | 0 | 0 |
| 3 | 0 | 0.430303 | 0.853454 | 0.170171 | 0.467424 | 0.35 | 0.329630 | 0.222222 | 1 | 0 |
| 4 | 0 | 0.684848 | 0.475184 | 0.407959 | 0.440526 | 0.15 | 0.505556 | 0.333333 | 1 | 0 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 2661 | 0 | 0.593939 | 0.383970 | 0.521514 | 0.533174 | 0.25 | 0.590741 | 0.222222 | 0 | 0 |
| 2662 | 1 | 0.466667 | 0.445171 | 0.592688 | 0.688583 | 0.30 | 0.494444 | 0.222222 | 0 | 1 |
| 2663 | 0 | 0.345455 | 0.658786 | 0.421870 | 0.452481 | 0.20 | 0.479630 | 0.333333 | 0 | 0 |
| 2664 | 0 | 0.660606 | 0.515426 | 0.794241 | 0.454274 | 0.30 | 0.705556 | 0.222222 | 0 | 0 |
| 2665 | 0 | 0.684848 | 0.668176 | 0.731155 | 0.586970 | 0.20 | 0.685185 | 0.000000 | 0 | 1 |
2666 rows × 10 columns
# Separação variável target de treino
targetTrain = dataOrigTf_scaled[dataOrigTf_scaled['Train']==1]['Churn_Yes']
targetTrain
0 0
1 0
2 0
3 0
4 0
..
2661 0
2662 0
2663 0
2664 0
2665 0
Name: Churn_Yes, Length: 2666, dtype: uint8
# Separação dados de teste
featuresTest = dataOrigTf_scaled[dataOrigTf_scaled['Train']==0][list(bfRfe)]
targetTest = dataOrigTf_scaled[dataOrigTf_scaled['Train']==0]['Churn_Yes']
# Definindo uma função, para treinar diferentes algoritmos, e prever a variável Target de um conjunto de dados.
def classifiersTraining(features, tTarget, printMeans = True, scoring = 'accuracy'):
# Definindo os valores do seed e do número de folds.
num_folds = 10
seed = 100
# Criando uma lista, para armazenar os modelos que serão utilizados.
models = []
# Criando Listas para armazenar os resultados e os nomes de cada um dos algoritmos testados.
results = []
names = []
# Criando um Dataframe para armazenar a média e o desvio-padrão de cada um dos algoritmos testados.
means = pd.DataFrame(columns = ['mean', 'std'])
# Adicionando os modelos a lista.
models.append(('LR' , LogisticRegression() ))
models.append(('LDA' , LinearDiscriminantAnalysis() ))
models.append(('NB' , GaussianNB() ))
models.append(('KNN' , KNeighborsClassifier() ))
models.append(('CART' , DecisionTreeClassifier() ))
models.append(('AdaBoost', AdaBoostClassifier() ))
models.append(('GB' , GradientBoostingClassifier() ))
models.append(('SVM' , SVC() ))
models.append(('RF' , RandomForestClassifier() ))
models.append(('XGBoost' , xgb.XGBClassifier(use_label_encoder=False, eval_metric='logloss')))
# Avaliando cada um dos modelos da lista de modelos.
for name, model in models:
# Instanciando um objeto da classe Kfold para criar os folds.
kfold = KFold(n_splits = num_folds, random_state = seed)
# Treinando o modelo com Cross Validation.
cv_results = cross_val_score(model, features, tTarget, cv = kfold, scoring = scoring)
# Adicionando os resultados gerados na lista de resultados.
results.append(cv_results)
# Adicionando o nome do modelo avaliado na lista de nomes.
names.append(name)
# Adicionando a média e o desvio-padrão, dos resultados gerados pelo modelo analisado, ao Dataframe de médias.
means = means.append (
pd.DataFrame (
data = [[cv_results.mean(), cv_results.std()]],
columns = ['mean', 'std'],
index = [name]
)
)
# Imprime uma mensagem, contendo os resultados obtidos ao fim do treinamento, de cada um dos modelos.
if printMeans:
# Cria a mensagem a ser impressa.
msg = "%s: %f (%f)" % (name, cv_results.mean(), cv_results.std())
# Imprime a mensagem.
print(msg)
# Cria um DataFrame, com os resultados obtidos por cada um dos modelos avaliados.
results = pd.DataFrame(np.transpose(results), columns = names)
# Retorna o DataFrame, com os resultados e com as médias geradas.
return (results, means)
# Definindo uma função para salvar um modelo preditivo já treinado.
def saveModel(name, model, fold = 'outputs/', ext = '.sav'):
# Definindo o diretório e o nome do arquivo que será utilizado para salvar o modelo.
dir = fold + name + ext
# Salvando o modelo especificado.
pickle.dump(model, open(dir, 'wb'))
# Imprimindo mensagem de sucesso.
print("Modelo salvo!")
# Definindo uma função para carregar um modelo preditivo já treinado.
def loadModel(name, fold = 'outputs/', ext = '.sav'):
# Definindo o diretório e o nome do arquivo que será utilizado para carregar o modelo.
dir = fold + name + ext
# Imprimindo mensagem de sucesso.
print("Modelo carregado!")
# Carregando o modelo especificado.
return pickle.load(open(dir, 'rb'))
# Treinando classificadores.
X = featuresTrain
y = targetTrain
resultsRFE = classifiersTraining (
features = X,
tTarget = y
)
LR: 0.862324 (0.024812) LDA: 0.858206 (0.022154) NB: 0.850707 (0.013262) KNN: 0.892343 (0.019905) CART: 0.917862 (0.013939) AdaBoost: 0.875472 (0.019966) GB: 0.951985 (0.011988) SVM: 0.886701 (0.023275) RF: 0.955740 (0.012875) XGBoost: 0.954242 (0.014024)
# Resultados dos treinos dos modelos
resultsRFE[0]
| LR | LDA | NB | KNN | CART | AdaBoost | GB | SVM | RF | XGBoost | |
|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0.868914 | 0.850187 | 0.857678 | 0.895131 | 0.906367 | 0.883895 | 0.947566 | 0.910112 | 0.962547 | 0.947566 |
| 1 | 0.876404 | 0.876404 | 0.857678 | 0.910112 | 0.895131 | 0.876404 | 0.962547 | 0.898876 | 0.958801 | 0.958801 |
| 2 | 0.910112 | 0.910112 | 0.861423 | 0.906367 | 0.932584 | 0.891386 | 0.955056 | 0.921348 | 0.966292 | 0.962547 |
| 3 | 0.861423 | 0.846442 | 0.857678 | 0.891386 | 0.910112 | 0.876404 | 0.955056 | 0.887640 | 0.943820 | 0.940075 |
| 4 | 0.861423 | 0.853933 | 0.853933 | 0.891386 | 0.925094 | 0.876404 | 0.951311 | 0.898876 | 0.951311 | 0.951311 |
| 5 | 0.838951 | 0.835206 | 0.831461 | 0.872659 | 0.917603 | 0.838951 | 0.947566 | 0.857678 | 0.947566 | 0.955056 |
| 6 | 0.890977 | 0.879699 | 0.872180 | 0.909774 | 0.924812 | 0.909774 | 0.962406 | 0.906015 | 0.969925 | 0.977444 |
| 7 | 0.830827 | 0.842105 | 0.834586 | 0.906015 | 0.921053 | 0.879699 | 0.951128 | 0.860902 | 0.954887 | 0.947368 |
| 8 | 0.827068 | 0.845865 | 0.849624 | 0.842105 | 0.902256 | 0.842105 | 0.921053 | 0.849624 | 0.928571 | 0.928571 |
| 9 | 0.857143 | 0.842105 | 0.830827 | 0.898496 | 0.943609 | 0.879699 | 0.966165 | 0.875940 | 0.973684 | 0.973684 |
# Média e Desvio padrão dos resultados dos treinos dos modelos
resultsRFE[1]
| mean | std | |
|---|---|---|
| LR | 0.862324 | 0.024812 |
| LDA | 0.858206 | 0.022154 |
| NB | 0.850707 | 0.013262 |
| KNN | 0.892343 | 0.019905 |
| CART | 0.917862 | 0.013939 |
| AdaBoost | 0.875472 | 0.019966 |
| GB | 0.951985 | 0.011988 |
| SVM | 0.886701 | 0.023275 |
| RF | 0.955740 | 0.012875 |
| XGBoost | 0.954242 | 0.014024 |
# Plotando os scores, da acurácia dos classificadores treinados, em boxplots.
plotBoxplot(data = resultsRFE[0])
# Definindo qual conjunto de dados de treino, já escalado, deve ser utilizado e a sua variável target.
trainX = featuresTrain
trainY = targetTrain
# Definindo os valores que devem ser testados, em cada um dos parâmetros do modelo especificado.
paramGrid = dict (
missing = [np.nan],
booster = ['gbtree','gblinear', 'dart'],
max_depth = [4, 5],
n_estimators = [300, 350],
learning_rate = [0.025, 0.03],
nthread = [4],
subsample = [0.95, 1],
colsample_bytree = [0.95, 1],
seed = [100],
use_label_encoder= [False],
eval_metric=['logloss']
)
# Criando uma instância da classe do modelo Xgboost.
model = xgb.XGBClassifier()
# Criando o grid, para fazer a busca dos melhores parâmetros para o modelo.
grid = GridSearchCV(estimator = model, param_grid = paramGrid, cv = 10, verbose = True, n_jobs = -1)
# Buscando pelos melhores parâmetros para o modelo.
grid.fit(trainX, trainY)
# Exibindo a configuração, do melhor modelo treinado.
print("\n" + "Melhores Parâmetros para o Modelo:" + "\n\n", grid.best_estimator_)
Fitting 10 folds for each of 96 candidates, totalling 960 fits
[Parallel(n_jobs=-1)]: Using backend LokyBackend with 4 concurrent workers. [Parallel(n_jobs=-1)]: Done 42 tasks | elapsed: 33.4s [Parallel(n_jobs=-1)]: Done 192 tasks | elapsed: 2.9min [Parallel(n_jobs=-1)]: Done 442 tasks | elapsed: 4.7min [Parallel(n_jobs=-1)]: Done 792 tasks | elapsed: 21.8min [Parallel(n_jobs=-1)]: Done 960 out of 960 | elapsed: 40.1min finished
Melhores Parâmetros para o Modelo:
XGBClassifier(base_score=0.5, booster='gbtree', colsample_bylevel=1,
colsample_bynode=1, colsample_bytree=0.95, eval_metric='logloss',
gamma=0, gpu_id=-1, importance_type='gain',
interaction_constraints='', learning_rate=0.03, max_delta_step=0,
max_depth=5, min_child_weight=1, missing=nan,
monotone_constraints='()', n_estimators=350, n_jobs=4, nthread=4,
num_parallel_tree=1, random_state=100, reg_alpha=0, reg_lambda=1,
scale_pos_weight=1, seed=100, subsample=0.95, tree_method='exact',
use_label_encoder=False, validate_parameters=1, verbosity=None)
# Criando o modelo, com a melhor configuração encontrada.
classifierXGB = xgb.XGBClassifier(
missing = np.nan,
booster = 'gbtree',
max_depth = 5,
n_estimators = 350,
learning_rate = 0.03,
nthread = 4,
subsample = 0.95,
colsample_bytree = 0.95,
seed = 100,
use_label_encoder= False,
eval_metric='logloss'
)
# Treinando o melhor modelo com os dados de treino.
classifierXGB.fit(X = trainX, y = trainY)
XGBClassifier(base_score=0.5, booster='gbtree', colsample_bylevel=1,
colsample_bynode=1, colsample_bytree=0.95, eval_metric='logloss',
gamma=0, gpu_id=-1, importance_type='gain',
interaction_constraints='', learning_rate=0.03, max_delta_step=0,
max_depth=5, min_child_weight=1, missing=nan,
monotone_constraints='()', n_estimators=350, n_jobs=4, nthread=4,
num_parallel_tree=1, random_state=100, reg_alpha=0, reg_lambda=1,
scale_pos_weight=1, seed=100, subsample=0.95, tree_method='exact',
use_label_encoder=False, validate_parameters=1, verbosity=None)
# Calculando a acurácia do modelo para o conjunto de dados de treino.
scoreTrainXGB = accuracy_score(trainY, classifierXGB.predict(trainX))
# Visualizando o resultado.
print('Acurácia para os dados de treino: ' + str(scoreTrainXGB))
Acurácia para os dados de treino: 0.9793698424606152
# Salvando o modelo preditivo especificado.
saveModel(name = 'classifierXGB', model = classifierXGB)
Modelo salvo!
# Carregando o modelo preditivo especificado.
classifierXGBopen = loadModel(name = 'classifierXGB')
Modelo carregado!
# Calculando a acurácia do modelo para o conjunto de dados de teste.
scoreTestXGB = accuracy_score(targetTest, classifierXGBopen.predict(featuresTest))
# Visualizando o resultado.
print('Acurácia para os dados de teste: ' + str(scoreTestXGB))
Acurácia para os dados de teste: 0.7931034482758621